package com.shop.cereshop.app.tencent.im.model.redpacket;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.shop.cereshop.app.tencent.im.utils.RedPacketUtils;
import com.shop.cereshop.commons.tencent.im.enums.redpacket.RedPacketAllocationStatusEnum;
import com.shop.cereshop.commons.tencent.im.enums.redpacket.RedPacketStatusEnum;
import com.shop.cereshop.commons.tencent.im.enums.redpacket.RedPacketTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

import javax.validation.constraints.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import static com.shop.cereshop.app.tencent.im.utils.RedPacketUtils.DEFAULT_BLESSING;
import static com.shop.cereshop.app.tencent.im.utils.RedPacketUtils.MIN_COUNT;

/**
 * @description: 发送红包请求参数
 * @author zdd
 * @date 2025/9/3 14:36
 * @version 1.0
 */
@ApiModel("发送红包请求参数")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CreateRedPacketParam implements Serializable {

    private static final long serialVersionUID = 1L;

    /** 红包ID，不需要传参，在创建红包时服务端生成 */
    @JsonIgnore
    private String packetId;

    @ApiModelProperty("发送者ID")
    private String senderId;

    @ApiModelProperty("发送者名称")
    @JsonIgnore
    private String senderName;

    @ApiModelProperty("群组ID (如果是单聊则为空)")
    private String groupId;

    @ApiModelProperty("接收者ID")
    private String receiverId;

    @ApiModelProperty("接收者名称")
    @JsonIgnore
    private String receiverName;

    @ApiModelProperty("祝福语")
    @Size(max = 20, message = "祝福语长度不能超过20个字符")
    private String blessing;

    @ApiModelProperty("红包封面")
    private String cover;

    @ApiModelProperty("红包类型：1-普通红包 2-拼手气红包 3-专属红包 (单聊时，设置为3)")
    @NotNull(message = "type不能为空")
    @Min(value = 1, message = "type不能小于1")
    @Max(value = 3, message = "type不能大于3")
    private Integer type;

    @ApiModelProperty("金额 (单位：元), 注意：type=1或type=3时，amount为单个红包金额；type=2时，amount为红包总金额")
    @NotNull(message = "amount不能为空")
    @DecimalMin(value = "0.01", message = "amount不能小于0.01元")
//    @DecimalMax(value = "200.00", message = "amount不能大于200元")
    private BigDecimal amount;

    @ApiModelProperty("数量")
    @Min(value = 1, message = "count不能小于1")
    @Max(value = 100, message = "count不能大于100")
    private Integer count;


    /**
     * 转换为RedPacket对象
     * @return RedPacket 红包实体对象
     */
    public RedPacket covertToRedPacket() {
        // 单聊红包，默认设置红包个数为1、类型为专属红包
        if (StringUtils.isBlank(this.getGroupId())) {
            this.setCount(MIN_COUNT);
            this.setType(RedPacketTypeEnum.EXCLUSIVE.getCode());
        }
        RedPacket redPacket = new RedPacket();
        redPacket.setPacketId(this.getPacketId());
        redPacket.setSenderId(this.getSenderId());
        redPacket.setSenderName(this.getSenderName());
        redPacket.setGroupId(this.getGroupId());
        redPacket.setReceiverId(this.getReceiverId());
        redPacket.setReceiverName(this.getReceiverName());
        redPacket.setPacketType(this.getType());

        // 单聊或者群聊专属红包时，设置红包个数为1
        boolean isExclusiveRedPacket = StringUtils.isBlank(this.getGroupId()) ||
                (StringUtils.isNotBlank(this.getGroupId())
                        && (RedPacketTypeEnum.EXCLUSIVE.getCode().equals(this.getType())));
        if (isExclusiveRedPacket){
            redPacket.setTotalCount(1);
            redPacket.setRemainCount(1);
        } else {
            redPacket.setTotalCount(this.getCount());
            redPacket.setRemainCount(this.getCount());
        }
        // 普通红包时，总金额 = 红包个数 * 单个红包金额
        if (RedPacketTypeEnum.NORMAL.getCode().equals(this.getType())) {
            BigDecimal totalAmount = this.getAmount().multiply(BigDecimal.valueOf(this.getCount()));
            redPacket.setRemainAmount(totalAmount);
            redPacket.setTotalAmount(totalAmount);
        } else {
            redPacket.setRemainAmount(amount);
            redPacket.setTotalAmount(amount);
        }

        redPacket.setBlessing(StringUtils.isBlank(this.getBlessing()) ? DEFAULT_BLESSING : this.getBlessing());
        redPacket.setCover(this.getCover());
        redPacket.setStatus(RedPacketStatusEnum.CREATE.getCode());

        redPacket.setCreateTime(LocalDateTime.now());
        // 24小时过期
//        redPacket.setExpireTime(nowed.plusHours(24));
        return redPacket;
    }

    /**
     * 转换为RedPacket对象
     * @return RedPacket 红包实体对象
     */
    public List<RedPacketAllocation> covertToRedPacketAllocationList() {
        List<RedPacketAllocation> list = new ArrayList<>();
        // 单聊红包，默认设置红包个数为1、类型为专属红包
        if (StringUtils.isBlank(this.getGroupId())) {
            this.setCount(MIN_COUNT);
            this.setType(RedPacketTypeEnum.EXCLUSIVE.getCode());
        }
        LocalDateTime allocationTime = LocalDateTime.now();
        // 因为设置了单聊红包的默认红包个数和红包类型，所以这里不需要再进行判断，直接从获取红包分配金额列表中获取
        List<BigDecimal> packets = RedPacketUtils.getRedPacketAmounts(this.getType(), this.getAmount(), this.getCount());
        if (CollUtil.isEmpty(packets)) {
            return list;
        }
        BigDecimal maxAmount = packets.stream()
                .max(Comparator.naturalOrder())
                .orElse(BigDecimal.ZERO);
        for (int i = 0; i < packets.size(); i++) {
            String index = "";
            if(i < 10){
                index = "00" + i + 1;
            } else if(i < 100) {
                index = "0" + i + 1;
            } else {
                index = "" + i + 1;
            }

            String allocationNo = String.format("%s_%s", this.getPacketId(), index);
            BigDecimal amount = packets.get(i);
            RedPacketAllocation allocation = new RedPacketAllocation();
            allocation.setPacketId(this.getPacketId());
            allocation.setAllocationNo(allocationNo);
            // 这里的amount转换为分
            allocation.setAmount(amount);
            // 分配金额最大的设置为手气最佳
            int isLuckiest = (maxAmount.compareTo(amount) == 0) ? 1 : 0;
            if (!RedPacketTypeEnum.LUCKY.getCode().equals(this.getType())){
                isLuckiest = 0;
            }
            allocation.setIsLuckiest(isLuckiest);
            allocation.setReceiveStatus(RedPacketAllocationStatusEnum.NOT_RECEIVED.getCode());
            allocation.setAllocationTime(allocationTime);
            list.add(allocation);
        }
        return list;
    }

}
